#include "Quad.h"
#include <cassert>
#include "SprQuad.h"

class SprQuad;



Quad::Quad(int id , int timeline) :mId(id), mTimeline(timeline), mType(Type::None), mQuadChildren(), mParent(nullptr)
{}

void Quad::attachChild(Quad::Ptr quadNode)
{
	quadNode->mParent = this;
	mQuadChildren.push_back(std::move(quadNode));
}

Quad::Ptr Quad::detachChild(const Quad& sprite)
{
	auto found = std::find_if(mQuadChildren.begin(), mQuadChildren.end(), 
		[&](Quad::Ptr& spr){return spr.get() == &sprite; });
	assert(found != mQuadChildren.end());

	Quad::Ptr result = std::move(*found);
	result->mParent = nullptr;
	mQuadChildren.erase(found);
	return result;
}

// gets the current Transform in the Tree
sf::Transform Quad::getWorldTransform()
{
	sf::Transform transform = sf::Transform::Identity;
	for (Quad* p = this; p != nullptr; p = p->mParent)
	{
		transform = p->getTransform()*transform;
	}
	return transform;
}

Quad* Quad::getQuadById(int id, Type sob)
{
	if (mType == sob && mId == id) 
		return this;
	if (mQuadChildren.size() != 0)
	{
		for (Quad::Ptr& ch : mQuadChildren)
		{
			Quad *temp = ch->getQuadById(id,sob);
			if (temp) return temp;	
		}
	}
}
	
void Quad::setTransformByID(int id, Type sob, const sf::Vector2f& pos, float angle, const sf::Vector2f& scale)
{
	Quad* foundQuad = getQuadById(id, sob);
	foundQuad->setScale(scale);
	foundQuad->setRotation(angle);
	foundQuad->setPosition(pos);	
}


void Quad::clearQuads()
{
	if (!mQuadChildren.empty())
		mQuadChildren.clear();
}

void Quad::getSprites(std::vector<SprQuad*>& sprites)
{
	if (mType == Type::Sprite)
	{
		// Check if cast is safe
		assert(dynamic_cast<SprQuad*>(this) != nullptr);

		sprites.push_back(static_cast<SprQuad*>(this));
	}

	for (Ptr& sQuad : mQuadChildren)
	{
		sQuad->getSprites(sprites);
	}
}


int Quad::getID() const 
{
	return mId;
}

int Quad::getTimeline() const
{
	return mTimeline;
}

